//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.eResearch.RuntimeServices.Monitoring.Monitors
{
    using System;
    using System.Diagnostics;
    using System.Globalization;

    [MonitorConcept("trident:CpuResource")]
    public class CpuMonitor : IResourceMonitor
    {
        private PerformanceCounter cpuCounter;

        private float cpuUsage;

        public TimeSpan MonitorTimeSpan
        {
            get { return TimeSpan.FromMilliseconds(500); }
        }

        public void Setup()
        {
            cpuUsage = 0.0f;

            // Monitor only the current process
            cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
        }

        public void Teardown()
        {
            cpuCounter.Close();
            cpuCounter.Dispose();
            cpuCounter = null;
        }

        public bool MonitorResource(ActivityMonitorEvent monitorEvent)
        {
            // Sometimes the timer can schedule a call to this method on the thread pool
            // that gets invoked even after the timer is disposed (i.e. TearDown was already called).
            // If this happens, just return without asking for a message to be sent.
            if (cpuCounter == null)
            {
                return false;
            }

            cpuUsage = cpuCounter.NextValue();
            return true;
        }

        public string GetResource()
        {
            return cpuUsage.ToString(CultureInfo.CurrentCulture);
        }
    }
}